#include "usart.hpp"
#include "system.hpp"

struct SerialPortResource {
    ::SerialPort *instance;
    USART_Register_t *reg;
    System::ClockChannel clock_channel;
    struct {
        ::SerialPort::EventCallback transmit_complete_callback;
        ::SerialPort::EventCallback data_received_callback;
        ::SerialPort::EventCallback idle_callback;
    } event_callbacks;
    struct BindedPin{
        int port_number;
        int pin_number;
    };
    struct BindedPins{
        struct BindedPin ck;
        struct BindedPin txd;
        struct BindedPin rxd;
        struct BindedPin cts;
        struct BindedPin rts;
    };
    struct BindedPins binded_pins[4];   /* Maximum count of remap channel is 4. */
} serial_port_resources[] = {
    /* USART1. */ 
    [0] = {
        .instance = nullptr,
        .reg = (USART_Register_t*)0x40013800,
        .clock_channel = System::ClockChannel::USART1,
        .event_callbacks = {
            .transmit_complete_callback = nullptr,
            .data_received_callback = nullptr,
            .idle_callback = nullptr,
        },
        .binded_pins = {
            [0] = {                                             /* Remap 1. */
                .ck = {.port_number = 0, .pin_number = 8, },    /* USART1-CK = PA8. */
                .txd = {.port_number = 0, .pin_number = 9, },   /* USART1-TXD = PA9. */
                .rxd = {.port_number = 0, .pin_number = 10, },  /* USART1-RXD = PA10. */
                .cts = {.port_number = 0, .pin_number = 11, },  /* USART1-CTS = PA11. */
                .rts = {.port_number = 0, .pin_number = 12, },  /* USART1-CTS = PA12. */
            },
            [1] = {                                             /* Remap 2. */
                .ck = {.port_number = 0, .pin_number = 8, },    /* USART1-CK = PA8. */
                .txd = {.port_number = 1, .pin_number = 6, },   /* USART1-TXD = PB6. */
                .rxd = {.port_number = 1, .pin_number = 7, },   /* USART1-RXD = PB7. */
                .cts = {.port_number = 0, .pin_number = 11, },  /* USART1-CTS = PA11. */
                .rts = {.port_number = 0, .pin_number = 12, },  /* USART1-RTS = PA12. */
            },
            [2] = {                                             /* Remap 3. */
                .ck = {.port_number = 0, .pin_number = 10, },   /* USART1-CK = PA10. */
                .txd = {.port_number = 1, .pin_number = 15, },  /* USART1-TXD = PB15. */
                .rxd = {.port_number = 0, .pin_number = 8, },   /* USART1-RXD = PA8. */
                .cts = {.port_number = 0, .pin_number = 5, },   /* USART1-CTS = PA5. */
                .rts = {.port_number = 0, .pin_number = 9, },   /* USART1-RTS = PA9. */
            },
            [3] = {                                             /* Remap 4. */
                .ck = {.port_number = 0, .pin_number = 5, },    /* USART1-CK = PA5. */
                .txd = {.port_number = 0, .pin_number = 6, },   /* USART1-TXD = PA6. */
                .rxd = {.port_number = 0, .pin_number = 7, },   /* USART1-RXD = PA7. */
                .cts = {.port_number = 2, .pin_number = 4, },   /* USART1-CTS = PC4. */
                .rts = {.port_number = 2, .pin_number = 5, },   /* USART1-RTS = PC5. */
            },
        }
    },
    /* USART2. */
    [1] = {
        .instance = nullptr,
        .reg = (USART_Register_t*)0x40004400,
        .clock_channel = System::ClockChannel::USART2,
        .event_callbacks = {
            .transmit_complete_callback = nullptr,
            .data_received_callback = nullptr,
            .idle_callback = nullptr,
        },
        .binded_pins = {
            [0] = {                                             /* Remap 1. */
                .ck = {.port_number = 0, .pin_number = 4, },    /* USART2-CK = PA4. */
                .txd = {.port_number = 0, .pin_number = 2, },   /* USART2-TXD = PA2. */
                .rxd = {.port_number = 0, .pin_number = 3, },   /* USART2-RXD = PA3. */
                .cts = {.port_number = 0, .pin_number = 0, },   /* USART2-CTS = PA0. */
                .rts = {.port_number = 0, .pin_number = 1, },   /* USART2-RTS = PA1. */
            },
            [1] = {                                             /* Remap 2. */
                .ck = {.port_number = 3, .pin_number = 7, },    /* USART2-CK = PD7. */
                .txd = {.port_number = 3, .pin_number = 5, },   /* USART2-TXD = PA2. */
                .rxd = {.port_number = 3, .pin_number = 6, },   /* USART2-RXD = PA3. */
                .cts = {.port_number = 3, .pin_number = 3, },   /* USART2-CTS = PA0. */
                .rts = {.port_number = 3, .pin_number = 4, },   /* USART2-RTS = PA1. */
            },
            [2] = {                                             /* Remap 3 not support. */
                .ck = {.port_number = -1, .pin_number = -1, },
                .txd = {.port_number = -1, .pin_number = -1, },
                .rxd = {.port_number = -1, .pin_number = -1, },
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [3] = {                                             /* Remap 4 not support. */
                .ck = {.port_number = -1, .pin_number = -1, },
                .txd = {.port_number = -1, .pin_number = -1, },
                .rxd = {.port_number = -1, .pin_number = -1, },
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
        }
    },
    /* USART3. */
    [2] = {
        .instance = nullptr,
        .reg = (USART_Register_t*)0x40004800,
        .clock_channel = System::ClockChannel::USART3,
        .event_callbacks = {
            .transmit_complete_callback = nullptr,
            .data_received_callback = nullptr,
            .idle_callback = nullptr,
        },
        .binded_pins = {
            [0] = {                                             /* Remap 1. */
                .ck = {.port_number = 1, .pin_number = 12, },   /* USART3-CK = PB12. */
                .txd = {.port_number = 1, .pin_number = 10, },  /* USART3-TXD = PB10. */
                .rxd = {.port_number = 1, .pin_number = 11, },  /* USART3-RXD = PB11. */
                .cts = {.port_number = 1, .pin_number = 13, },  /* USART3-CTS = PB13. */
                .rts = {.port_number = 1, .pin_number = 14, },  /* USART3-RTS = PB14. */
            },
            [1] = {                                             /* Remap 2. */
                .ck = {.port_number = 2, .pin_number = 12, },   /* USART3-CK = PC12. */
                .txd = {.port_number = 2, .pin_number = 10, },  /* USART3-TXD = PC10. */
                .rxd = {.port_number = 2, .pin_number = 11, },  /* USART3-RXD = PC11. */
                .cts = {.port_number = 1, .pin_number = 13, },  /* USART3-CTS = PB13. */
                .rts = {.port_number = 1, .pin_number = 14, },  /* USART3-RTS = PB14. */
            },
            [2] = {                                             /* Remap 3. */
                .ck = {.port_number = 3, .pin_number = 10, },   /* USART3-CK = PD10. */
                .txd = {.port_number = 0, .pin_number = 13, },  /* USART3-TXD = PA13. */
                .rxd = {.port_number = 0, .pin_number = 14, },  /* USART3-RXD = PA14. */
                .cts = {.port_number = 3, .pin_number = 11, },  /* USART3-CTS = PD11. */
                .rts = {.port_number = 3, .pin_number = 12, },  /* USART3-RTS = PD12. */
            },
            [3] = {                                             /* Remap 4. */
                .ck = {.port_number = 1, .pin_number = 12, },   /* USART3-CK = PD10. */
                .txd = {.port_number = 1, .pin_number = 10, },  /* USART3-TXD = PD8. */
                .rxd = {.port_number = 1, .pin_number = 11, },  /* USART3-RXD = PD9. */
                .cts = {.port_number = 1, .pin_number = 13, },  /* USART3-CTS = PD11. */
                .rts = {.port_number = 1, .pin_number = 14, },  /* USART3-RTS = PD12. */
            },
        }
    },
    /* UART4. */
    [3] = {
        .instance = nullptr,
        .reg = (USART_Register_t*)0x40004c00,
        .clock_channel = System::ClockChannel::USART4,
        .event_callbacks = {
            .transmit_complete_callback = nullptr,
            .data_received_callback = nullptr,
            .idle_callback = nullptr,
        },
        .binded_pins = {
            [0] = {                                             /* Remap 1. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART4 have not CK. */
                .txd = {.port_number = 2, .pin_number = 10, },  /* UART4-TXD = PC10. */
                .rxd = {.port_number = 2, .pin_number = 11, },  /* UART4-RXD = PC11. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [1] = {                                             /* Remap 2. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART4 have not CK. */
                .txd = {.port_number = 1, .pin_number = 0, },   /* UART4-TXD = PB0. */
                .rxd = {.port_number = 1, .pin_number = 1, },   /* UART4-RXD = PB1. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [2] = {                                             /* Remap 3. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART4 have not CK. */
                .txd = {.port_number = 4, .pin_number = 0, },   /* UART4-TXD = PE0. */
                .rxd = {.port_number = 4, .pin_number = 1, },   /* UART4-RXD = PE1. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [3] = {                                             /* Remap 4. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART4 have not CK. */
                .txd = {.port_number = 4, .pin_number = 0, },   /* UART4-TXD = PE0. */
                .rxd = {.port_number = 4, .pin_number = 1, },   /* UART4-RXD = PE1. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
        },
    },
    /* UART5. */
    [4] = {
        .instance = nullptr,
        .reg = (USART_Register_t*)0x40005000,
        .clock_channel = System::ClockChannel::USART5,
        .event_callbacks = {
            .transmit_complete_callback = nullptr,
            .data_received_callback = nullptr,
            .idle_callback = nullptr,
        },
        .binded_pins = {
            [0] = {                                             /* Remap 1. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART5 have not CK. */
                .txd = {.port_number = 2, .pin_number = 12, },  /* UART5-TXD = PC12. */
                .rxd = {.port_number = 3, .pin_number = 2, },   /* UART5-RXD = PD2. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [1] = {                                             /* Remap 2. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART5 have not CK. */
                .txd = {.port_number = 1, .pin_number = 4, },   /* UART5-TXD = PB4. */
                .rxd = {.port_number = 1, .pin_number = 5, },   /* UART5-RXD = PB5. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [2] = {                                             /* Remap 3. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART5 have not CK. */
                .txd = {.port_number = 4, .pin_number = 8, },   /* UART5-TXD = PE8. */
                .rxd = {.port_number = 4, .pin_number = 9, },   /* UART5-RXD = PE9. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [3] = {                                             /* Remap 4. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART5 have not CK. */
                .txd = {.port_number = 4, .pin_number = 8, },   /* UART5-TXD = PE8. */
                .rxd = {.port_number = 4, .pin_number = 9, },   /* UART5-RXD = PE9. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
        },
    },
    /* UART6. */
    [5] = {
        .instance = nullptr,
        .reg = (USART_Register_t*)0x40001800,
        .clock_channel = System::ClockChannel::USART6,
        .event_callbacks = {
            .transmit_complete_callback = nullptr,
            .data_received_callback = nullptr,
            .idle_callback = nullptr,
        },
        .binded_pins = {
            [0] = {                                             /* Remap 1. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART6 have not CK. */
                .txd = {.port_number = 2, .pin_number = 0, },   /* UART6-TXD = PC0. */
                .rxd = {.port_number = 2, .pin_number = 1, },   /* UART6-RXD = PC1. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [1] = {                                             /* Remap 2. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART6 have not CK. */
                .txd = {.port_number = 1, .pin_number = 8, },   /* UART6-TXD = PB8. */
                .rxd = {.port_number = 1, .pin_number = 9, },   /* UART6-RXD = PB9. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [2] = {                                             /* Remap 3. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART6 have not CK. */
                .txd = {.port_number = 4, .pin_number = 10, },  /* UART6-TXD = PE10. */
                .rxd = {.port_number = 4, .pin_number = 11, },  /* UART6-RXD = PE11. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [3] = {                                             /* Remap 4. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART6 have not CK. */
                .txd = {.port_number = 4, .pin_number = 10, },  /* UART6-TXD = PE10. */
                .rxd = {.port_number = 4, .pin_number = 11, },  /* UART6-RXD = PE11. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
        },
    },
    /* UART7. */
    [6] = {
        .instance = nullptr,
        .reg = (USART_Register_t*)0x40001c00,
        .clock_channel = System::ClockChannel::USART7,
        .event_callbacks = {
            .transmit_complete_callback = nullptr,
            .data_received_callback = nullptr,
            .idle_callback = nullptr,
        },
        .binded_pins = {
            [0] = {                                             /* Remap 1. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART7 have not CK. */
                .txd = {.port_number = 2, .pin_number = 2, },   /* UART7-TXD = PC2. */
                .rxd = {.port_number = 2, .pin_number = 3, },   /* UART7-RXD = PC3. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [1] = {                                             /* Remap 2. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART7 have not CK. */
                .txd = {.port_number = 0, .pin_number = 6, },   /* UART7-TXD = PA6. */
                .rxd = {.port_number = 0, .pin_number = 7, },   /* UART7-RXD = PA7. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [2] = {                                             /* Remap 3. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART7 have not CK. */
                .txd = {.port_number = 4, .pin_number = 12, },  /* UART7-TXD = PE12. */
                .rxd = {.port_number = 4, .pin_number = 13, },  /* UART7-RXD = PE13. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [3] = {                                             /* Remap 4. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART7 have not CK. */
                .txd = {.port_number = 4, .pin_number = 12, },  /* UART7-TXD = PE12. */
                .rxd = {.port_number = 4, .pin_number = 13, },  /* UART7-RXD = PE13. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
        },
    },
    /* UART8. */
    [6] = {
        .instance = nullptr,
        .reg = (USART_Register_t*)0x40002000,
        .clock_channel = System::ClockChannel::USART8,
        .event_callbacks = {
            .transmit_complete_callback = nullptr,
            .data_received_callback = nullptr,
            .idle_callback = nullptr,
        },
        .binded_pins = {
            [0] = {                                             /* Remap 1. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART8 have not CK. */
                .txd = {.port_number = 2, .pin_number = 4, },   /* UART8-TXD = PC4. */
                .rxd = {.port_number = 2, .pin_number = 5, },   /* UART8-RXD = PC5. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [1] = {                                             /* Remap 2. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART8 have not CK. */
                .txd = {.port_number = 0, .pin_number = 14, },  /* UART8-TXD = PA14. */
                .rxd = {.port_number = 0, .pin_number = 15, },  /* UART8-RXD = PA15. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [2] = {                                             /* Remap 3. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART8 have not CK. */
                .txd = {.port_number = 4, .pin_number = 14, },  /* UART8-TXD = PE14. */
                .rxd = {.port_number = 4, .pin_number = 15, },  /* UART8-RXD = PE15. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
            [3] = {                                             /* Remap 4. */
                .ck = {.port_number = -1, .pin_number = -1, },  /* UART8 have not CK. */
                .txd = {.port_number = 4, .pin_number = 14, },  /* UART8-TXD = PE14. */
                .rxd = {.port_number = 4, .pin_number = 15, },  /* UART8-RXD = PE15. */
                .cts = {.port_number = -1, .pin_number = -1, },
                .rts = {.port_number = -1, .pin_number = -1, },
            },
        },
    },
};